package com.ybkj.daijia.server.controller;

import com.ybkj.daijia.serverUtils.HttpClientUtil;
import com.ybkj.daijia.ServiceSetting;
import com.ybkj.daijia.serverUtils.ServiceUtil;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.RandomString;
import com.ybkj.daijia.server.exception.NoPermissionException;
import com.ybkj.daijia.rest.JSONCheckStatus;
import com.ybkj.daijia.server.event.model.OperationLogEvent;
import com.ybkj.daijia.server.model.Admin;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.SmsTemplet;
import com.ybkj.daijia.server.model.SmsTemplet.SmsType;
import com.ybkj.daijia.server.service.AdminService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.SmsService;
import com.ybkj.daijia.server.utils.IPUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nl.captcha.Captcha;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @Autowired
    private SmsService smsService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private HttpServletRequest request;

    public static void main(String[] args) {

//    Sha256Hash hash = new Sha256Hash("NGQzZGZjM2U0ZjBkMDI0YTZiYjZhMjZhMGQwZDUzZDM=", Admin.SALT_KEY);
//    System.out.println(hash.toBase64());
        Logger log = LoggerFactory.getLogger("db");
        log.info("test");
    }

    @RequestMapping(value = {"", "/", "login"})
    public String login(Model model, HttpServletRequest request) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        if (null != principal) {

            ServiceSetting serviceSetting = ServiceUtil.checkOpen();
            if (serviceSetting.isDaijia() && currentUser.isPermitted("order")) {
                return "redirect:/order/daijialist";
            } else if (serviceSetting.isZhuanche() && currentUser.isPermitted("zhuan")) {
                return "redirect:/zhuanche/orderlist";
            } else if (serviceSetting.isPaotui() && currentUser.isPermitted("errand")) {
                return "redirect:/errand/errandList";
            } else if (serviceSetting.isFreight() && currentUser.isPermitted("freight")) {
                return "redirect:/freight/freightList";
            } else if (serviceSetting.isZuche() && currentUser.isPermitted("rentorder")) {
                return "redirect:/rentorder/neworder";
            } else if (serviceSetting.isZhuanxian() && currentUser.isPermitted("zhuanxian")) {
                return "redirect:/zhuanxian/orderList";
            }
        }

        return "login";
    }

    @RequestMapping(value = "jump", method = RequestMethod.GET)
    public String jump(Model model, HttpServletRequest request, @Param("jump") String jump) {
        Subject currentUser = SecurityUtils.getSubject();
        ServiceSetting serviceSetting = ServiceUtil.checkOpen();
        if (null != jump && jump.equals("jump")) {
            return "redirect:/boss/reporting";
        }
        if (serviceSetting.isDaijia() && currentUser.isPermitted("order")) {
            return "redirect:/order/daijialist";
        } else if (serviceSetting.isZhuanche() && currentUser.isPermitted("zhuan")) {
            return "redirect:/zhuanche/orderlist";
        } else if (serviceSetting.isPaotui() && currentUser.isPermitted("errand")) {
            return "redirect:/errand/errandList";
        } else if (serviceSetting.isFreight() && currentUser.isPermitted("freight")) {
            return "redirect:/freight/freightList";
        } else if (serviceSetting.isZuche() && currentUser.isPermitted("rentorder")) {
            return "redirect:/rentorder/neworder";
        } else if (serviceSetting.isZhuanxian()) {
            return "redirect:/zhuanxian/orderList";
        } else if (serviceSetting.isGasstation()) {
            return "redirect:/gasstation/list";
        }
        return "login";
    }

    @RequestMapping(value = "changepassword", method = RequestMethod.GET)
    public String changepassword(Model model) {
        return "password";
    }

    @RequestMapping(value = "changepassword", method = RequestMethod.POST)
    public String changepassword(Model model, String oldpassword, String password) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Admin local = adminService.findOne(principal.getId());
        if (!local.getPassword().equals((new Sha256Hash(oldpassword, Admin.SALT_KEY)).toBase64())) {
            model.addAttribute("success", false);
            model.addAttribute("message", "原密码不正确");
            return "password";
        }

        Sha256Hash hash = new Sha256Hash(password, Admin.SALT_KEY);
        local.setPassword(hash.toBase64());
        adminService.updateByPrimaryKey(local);
        model.addAttribute("success", true);
        model.addAttribute("message", "修改成功");

        return "password";

    }

    @RequestMapping(value = "err_404")
    public ModelAndView err_404() {

        ModelAndView mv = new ModelAndView();
        mv.setViewName("404");
        return mv;

    }

    @RequestMapping(value = "err_500")
    public ModelAndView err_500() {

        ModelAndView mv = new ModelAndView();
        mv.setViewName("500");
        return mv;

    }

    @RequestMapping(value = "nopermission", method = RequestMethod.GET)
    public String nopermission(Model model) {
        return "nopermission";
    }

    @RequestMapping(value = "debts", method = RequestMethod.GET)
    public String debts(Model model) {

        Setting setting = settingUtils.get();

        StringBuilder sb = new StringBuilder();
        sb.append("secKey").append("=").append(setting.getSecKey());

        JSONCheckStatus jcs = new JSONCheckStatus();
        try {
            jcs = HttpClientUtil.checkLogin(
                "http://dj.easymin.com/api/rest/app/driverapp/checkStatus" + "?" + sb.toString());
        } catch (Exception e) {

        }

        model.addAttribute("result", jcs);

        return "debts/debts";
    }

    @RequestMapping(value = "debtsPay", method = RequestMethod.GET)
    public String debtsPay(Model model) {

        Setting setting = settingUtils.get();

        StringBuilder sb = new StringBuilder();
        sb.append("secKey").append("=").append(setting.getSecKey());

        try {

            String result = HttpClientUtil
                .debtsPay("http://dj.easymin.com/api/rest/pay/driverapp" + "?" + sb.toString());

            model.addAttribute("result", result);

            return "debts/pay";

        } catch (Exception e) {

            model.addAttribute("result", e.getMessage());
            return "debts/pay";

        }

    }

    @RequestMapping(value = "videohelp", method = RequestMethod.GET)
    public String videohelp(Model model) {
        return "common/videohelp";
    }

    @RequestMapping(value = "documenthelp", method = RequestMethod.GET)
    public String documenthelp(Model model) {
        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("documenthelp")) {
            return "common/documenthelp";
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "checkusps", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> checkusps(
        HttpServletResponse response, HttpServletRequest request,
        String username, String password, String captcha) {
        Map<String, Object> map = new HashMap<String, Object>();

        String ip = IPUtils.getIp(request);
        if (ip.contains("alert") || ip.contains("script") || ip.contains("8.8.8.8")) {
            map.put("success", false);
            map.put("result", "500");
            return map;
        }

        Principal temp_principal = new Principal(0L, StringUtils.isBlank(username) ? ip : username);
        temp_principal.setHost(ip);
        Captcha c = (Captcha) ((HttpServletRequest) request).getSession().getAttribute(Captcha.NAME);
        // 验证用户名密码是否为空
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password) || StringUtils.isBlank(captcha)) {
            String detail = "【%s】登录系统，用户名/密码/验证码为空，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "UnknownAccount");
            return map;
        }
        // 三级等保 数据过长
        if (username.length() > 30 || password.length() > 50 || captcha.length() > 4) {
            String detail = "【%s】登录系统，用户名/密码/验证码过长，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "UnknownAccount");
            return map;
        }

        if (c == null || c.getAnswer() == null) {
            String detail = "【%s】登录系统，请先获取验证码，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "UnknownAccount");
            return map;
        }

        Admin admin = adminService.findByUsername(username);
        if (!captcha.equals(c.getAnswer())) {
//      if (!username.equals("shine")) {
//        adminService.addLoginFailed(admin.getId());
//      }
//
//      if (admin.getLoginFailed() >= 2) {
//        adminService.lockUser(admin.getId());
//
//        String detail = "【%s】登录系统，验证码连续错误三次，用户被禁用，后台登录。";
//        OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
//        applicationEventMulticaster.multicastEvent(operationLogEvent);
//
//        request.getSession().removeAttribute(Captcha.NAME);
//
//        map.put("success", false);
//        map.put("result", "DisabledAccount");
//        return map;
//      }
            String detail = "【%s】登录系统，验证码错误，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "UnknownAccount");
            return map;
        }
        // 验证用户是否存在
        if (null == admin) {
            String detail = "【%s】登录系统，用户不存在，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "UnknownAccount");
            return map;
        }
        // 判断管理员是否禁用
        if (admin.getIsLocked()) {
            String detail = "【%s】登录系统，用户被禁用，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "DisabledAccount");
            return map;
        }
        Sha256Hash hash = new Sha256Hash(password, Admin.SALT_KEY);
        // 密码匹配
        if (admin.getPassword().equals(hash.toBase64())) {
            //开启了短信登录
            if (admin.isPhoneLogin()) {
                if (StringUtils.isBlank(admin.getPhone())) {
                    map.put("success", false);
                    map.put("result", "AccountPhoneNull");
                    return map;
                } else {
                    //进行第二步短信登录
                    Integer messageTime = adminService.selectMessageTime(admin.getUsername());
                    String newCode = String.valueOf(RandomString.randomNum(4));
                    try {
                        if (messageTime.intValue() <= 10) {
                            String content = "您的帐号：" + username + "登录校验码为：" + newCode;
                            SmsTemplet templet = smsService
                                .findByAlias(admin.getCompanyId(), SmsType.custom);
                            if (null == templet) {
                                SmsTemplet smsTemplet = new SmsTemplet();
                                smsTemplet.setSmsType(SmsType.custom);
                                smsTemplet.setCompanyId(admin.getCompanyId());
                                smsTemplet.setContent("{content}");
                                smsService
                                    .insertSmsTemplate("自定义短信", SmsTemplet.SMSTEMPLATE_TYPE_CODE,
                                        smsTemplet);
                            }
                            if (templet != null && StringUtils.isNotBlank(templet.getContent())) {
                                Company company = companyService.findOne(admin.getCompanyId());
                                smsService.sendSms(admin.getPhone(), "custom",
                                    "{\"content\":\"" + content + "\"}", admin.getCompanyId(), 2,
                                    company.getSignName());
                                messageTime += 1;
                                adminService.setMessageTime(admin.getUsername(), messageTime);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    admin.setVcode(newCode);
                    admin.setExpired(new Date());
                    adminService.updateVcode(admin);
                    map.put("result", "startPhoneLogin");
                    map.put("phone", admin.getPhone().substring(admin.getPhone().length() - 4));
                    map.put("success", true);
//                    request.getSession().removeAttribute(Captcha.NAME);
                    return map;
                }
            }
            //直接登录
            else {
                map.put("result", "Login");
                map.put("success", true);
                return map;
            }
        } else {
//      if (!username.equals("shine")) {
//        adminService.addLoginFailed(admin.getId());
//      }
//
//      if (admin.getLoginFailed() >= 2) {
//        adminService.lockUser(admin.getId());
//
//        String detail = "【%s】登录系统，密码连续错误三次，用户被禁用，后台登录。";
//        OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
//        applicationEventMulticaster.multicastEvent(operationLogEvent);
//
//        request.getSession().removeAttribute(Captcha.NAME);
//
//        map.put("success", false);
//        map.put("result", "DisabledAccount");
//        return map;
//      }
            String detail = "【%s】登录系统，密码错误，后台登录。";
            OperationLogEvent operationLogEvent = new OperationLogEvent(temp_principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);
            request.getSession().removeAttribute(Captcha.NAME);
            map.put("success", false);
            map.put("result", "UnknownAccount");
            return map;
        }
    }

    @RequestMapping(value = "checkvcode", method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> checkvcode(
        HttpServletResponse response, HttpServletRequest request,
        String username, String vcode) {

        Map<String, Object> map = new HashMap<String, Object>();

        Admin admin = adminService.findByUsername(username);
        if (!admin.getVcode().equals(vcode)) {
            map.put("success", false);
            map.put("result", "vcodewrong");
            return map;
        }

        long time = (System.currentTimeMillis() - admin.getExpired().getTime()) / 1000;//多少秒
        if (time >= 60 * 30) {//30分
            map.put("success", false);
            map.put("result", "vcodeinvalid");
            return map;
        }

        map.put("success", true);
        return map;

    }
}
